using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ICP_MS;

public class iMassProcess
{
	public iMassClient client = new iMassClient();

	public Method method = new Method();

	public bool IsRun = false;

	public ExperimentService experimentService = new ExperimentService();

	private AutoTuneExperiment autoTune = new AutoTuneExperiment();

	private static iMassProcess _instance;

	public static iMassProcess Instance
	{
		get
		{
			if (_instance == null)
			{
				_instance = new iMassProcess();
			}
			return _instance;
		}
	}

	public static event EventHandler<CMDEventArgs> CMDEvent;

	public static event EventHandler<ShowMsgEventArgs> ShowMsgEvent;

	public static void ShowMsg(string msg)
	{
		if (iMassProcess.ShowMsgEvent != null)
		{
			iMassProcess.ShowMsgEvent(null, new ShowMsgEventArgs(msg));
		}
	}

	public bool Init()
	{
		iMassClient.DataEvent += IMassClient_DataEvent;
		ExperimentService.StatusEvent += ExperimentService_StatusEvent;
		IsRun = client.Init();
		return IsRun;
	}

	private void ExperimentService_StatusEvent(object sender, iMassDataEventArgs e)
	{
		SendData(e.Msg);
	}

	public void Dispose()
	{
		IsRun = false;
		iMassClient.DataEvent -= IMassClient_DataEvent;
		ExperimentService.StatusEvent -= ExperimentService_StatusEvent;
		if (experimentService != null)
		{
			experimentService.IsRun = false;
		}
		if (autoTune != null)
		{
			autoTune.isTuning = false;
		}
		client.Close();
	}

	private void IMassClient_DataEvent(object sender, DataProceeEventArgs e)
	{
		try
		{
			string frame = e.Frame;
			ShowMsg("Receive Frame:" + frame);
			JObject obj = (JObject)JsonConvert.DeserializeObject(frame);
			if (!obj.ContainsKey("CMD"))
			{
				return;
			}
			int cmd = obj.Value<int>("CMD");
			string json = "";
			switch (cmd)
			{
			case 1:
				json = GenerateJson.ConnectHost();
				SendData(json);
				SetClientEvent();
				break;
			case 2:
			{
				int status = 0;
				if (Vacuum.vacumm.ReadMode == 5 && experimentService.IsRun && experimentService.IsStable)
				{
					status = 7;
				}
				else if (Vacuum.vacumm.ReadMode == 5 && experimentService.IsRun)
				{
					status = 8;
				}
				else if (Vacuum.vacumm.ReadMode == 5 && autoTune.isTuning)
				{
					status = 9;
				}
				else
				{
					switch (Vacuum.vacumm.ReadMode)
					{
					case 0:
						status = 1;
						break;
					case 1:
						status = 6;
						break;
					case 2:
						status = 3;
						break;
					case 3:
						status = 2;
						break;
					case 4:
						status = 4;
						break;
					case 5:
						status = 5;
						break;
					}
				}
				json = GenerateJson.GetStatus(status);
				SendData(json);
				SetClientEvent();
				break;
			}
			case 3:
				if (iMassProcess.CMDEvent != null)
				{
					iMassProcess.CMDEvent(null, new CMDEventArgs(1));
				}
				break;
			case 10:
				if (iMassProcess.CMDEvent != null)
				{
					iMassProcess.CMDEvent(null, new CMDEventArgs(2));
				}
				break;
			case 6:
			{
				method.TuneMode = obj.Value<int>("Tune");
				method.ScanTimes = obj.Value<int>("ScanTimes");
				method.Sweeps = obj.Value<int>("Sweep");
				method.Channels = obj.Value<int>("Channels");
				method.Masses = obj.Value<JArray>("Masses").ToObject<List<double>>();
				method.Dwells = obj.Value<JArray>("Dwells").ToObject<List<double>>();
				experimentService.method = method;
				bool te = experimentService.SetConfig();
				json = GenerateJson.SetParam(te);
				SendData(json);
				SetClientEvent();
				break;
			}
			case 5:
				StartAnalysis();
				break;
			case 7:
				StopAnalysis();
				break;
			case 8:
				switch (obj.Value<int>("Type"))
				{
				case 0:
					if (autoTune.isTuning)
					{
						string json2 = GenerateJson.CheckFinished(2);
						SendData(json2);
						SetClientEvent();
						break;
					}
					Task.Factory.StartNew(delegate
					{
						string name = ((obj.Value<int>("Mode") == 0) ? "标准模式" : "KED模式");
						autoTune = AutoTuneExperiment.LoadConfig(name);
						autoTune.EventTuneFinish += AutoTune_EventTuneFinish;
						autoTune.EventTuneMsg += AutoTune_EventTuneMsg;
						autoTune.SetConfig();
						Thread.Sleep(2000);
						autoTune.StartTune();
					});
					break;
				case 1:
					autoTune.isTuning = false;
					break;
				}
				break;
			case 4:
			case 9:
				break;
			}
		}
		catch (Exception ex)
		{
			ShowMsg($"处理失败:{ex.Message}");
		}
	}

	private void AutoTune_EventTuneMsg(object sender, MsgEventArgs e)
	{
		ShowMsg(e.Message);
	}

	private void AutoTune_EventTuneFinish(object sender, EventArgs e)
	{
		if (autoTune.TuneSucceed)
		{
			string json = GenerateJson.CheckFinished(0);
			SendData(json);
			SetClientEvent();
		}
		else
		{
			string json2 = GenerateJson.CheckFinished(1);
			SendData(json2);
			SetClientEvent();
		}
		autoTune.EventTuneFinish -= AutoTune_EventTuneFinish;
		autoTune.EventTuneMsg -= AutoTune_EventTuneMsg;
	}

	public void SendData(string frame)
	{
		ShowMsg("Send Frame:" + frame);
		client.SendDatas(frame);
	}

	public void PlasmaOn(int status)
	{
		string json = GenerateJson.PlasmaOn(status);
		SendData(json);
		SetClientEvent();
	}

	public void PlasmaOff(int status)
	{
		string json = GenerateJson.PlasmaOff(status);
		SendData(json);
		SetClientEvent();
	}

	public void InstrumentCheck(int status)
	{
		string json = GenerateJson.CheckFinished(status);
		SendData(json);
	}

	public void ReturnData(int haveError, int errors, int sweepindex, int runindex, int channels, List<double> results)
	{
		string jsontext = GenerateJson.ReturnData(haveError, errors, sweepindex, runindex, channels, results);
		SendData(jsontext);
	}

	private void StartAnalysis()
	{
		Task.Factory.StartNew(delegate
		{
			experimentService.StartAnalysis();
		});
	}

	private void StopAnalysis()
	{
		experimentService.StopRun();
		SetClientEvent();
	}

	public void SetClientEvent()
	{
		client.processEvent.Set();
	}
}
